using Oracle.ManagedDataAccess.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Reflection;

namespace Lzfy_His_Service.Services
{
    /// <summary>
    /// Oracle连接池优化器 - 基于DbHelperHisBi模式
    /// 提供连接池配置优化和动态调整
    /// </summary>
    public class OracleConnectionPoolOptimizer
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<OracleConnectionPoolOptimizer> _logger;
        private readonly string _connectionStringName = "HisOracleConnection";

        public OracleConnectionPoolOptimizer(
            IConfiguration configuration,
            ILogger<OracleConnectionPoolOptimizer> logger)
        {
            _configuration = configuration;
            _logger = logger;
        }

        #region 连接池配置优化

        /// <summary>
        /// 优化连接池配置 - 基于DbHelperHisBi最佳实践
        /// </summary>
        public Dictionary<string, string> GetOptimizedConnectionSettings()
        {
            return new Dictionary<string, string>
            {
                ["Connection Timeout"] = "60",           // 连接超时60秒
                ["Min Pool Size"] = "10",               // 最小连接池10
                ["Max Pool Size"] = "100",              // 最大连接池100
                ["Incr Pool Size"] = "10",              // 每次增加10个连接
                ["Decr Pool Size"] = "5",               // 每次减少5个连接
                ["Connection Lifetime"] = "300",         // 连接生命周期5分钟
                ["Validate Connection"] = "true",         // 验证连接
                ["Statement Cache Size"] = "200",         // 语句缓存200
                ["Self Tuning"] = "true",                // 启用自适应调整
                ["Pooling"] = "true",                   // 启用连接池
                ["Load Balancing"] = "true"             // 启用负载均衡
            };
        }

        /// <summary>
        /// 构建优化后的连接字符串
        /// </summary>
        public string BuildOptimizedConnectionString()
        {
            var baseConnectionString = _configuration.GetConnectionString(_connectionStringName);
            if (string.IsNullOrEmpty(baseConnectionString))
            {
                _logger.LogError("连接字符串未配置: {ConnectionStringName}", _connectionStringName);
                return string.Empty;
            }
            var optimizedSettings = GetOptimizedConnectionSettings();

            // 移除现有连接池设置
            var parts = baseConnectionString.Split(';')
                .Where(p => !string.IsNullOrWhiteSpace(p) && 
                           !optimizedSettings.ContainsKey(p.Split('=')[0].Trim()))
                .ToList();

            // 添加优化设置
            parts.AddRange(optimizedSettings.Select(kvp => $"{kvp.Key}={kvp.Value}"));

            return string.Join(";", parts);
        }

        #endregion

        #region 连接池状态监控

        /// <summary>
        /// 获取连接池详细状态
        /// </summary>
        public ConnectionPoolStats GetPoolStats()
        {
            try
            {
                var connectionString = _configuration.GetConnectionString(_connectionStringName);
                if (string.IsNullOrEmpty(connectionString))
                {
                    _logger.LogError("连接字符串未配置: {ConnectionStringName}", _connectionStringName);
                    return new ConnectionPoolStats { IsHealthy = false };
                }
                var connectionStringHash = connectionString.GetHashCode();

                // 使用反射获取连接池状态
                var poolStats = GetOracleConnectionPoolStats(connectionStringHash);

                return new ConnectionPoolStats
                {
                    ConnectionStringHash = connectionStringHash,
                    Timestamp = DateTime.Now,
                    TotalConnections = poolStats?.TotalConnections ?? 0,
                    FreeConnections = poolStats?.FreeConnections ?? 0,
                    UsedConnections = poolStats?.UsedConnections ?? 0,
                    PooledConnections = poolStats?.PooledConnections ?? 0,
                    PoolSize = poolStats?.PoolSize ?? 0,
                    MaxPoolSize = 100,
                    MinPoolSize = 10,
                    ConnectionTimeout = 60,
                    IsHealthy = poolStats?.IsHealthy ?? true
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取连接池状态失败");
                return new ConnectionPoolStats { IsHealthy = false };
            }
        }

        /// <summary>
        /// 清理连接池 - 基于DbHelperHisBi模式
        /// </summary>
        public async Task<bool> ClearPoolAsync()
        {
            try
            {
                var connectionString = _configuration.GetConnectionString(_connectionStringName);
                if (string.IsNullOrEmpty(connectionString))
                {
                    _logger.LogError("连接字符串未配置: {ConnectionStringName}", _connectionStringName);
                    return false;
                }
                using (var connection = new OracleConnection(connectionString))
                {
                    OracleConnection.ClearPool(connection);
                    _logger.LogInformation("连接池清理完成");
                    
                    // 验证清理效果
                    await Task.Delay(1000);
                    var stats = GetPoolStats();
                    
                    return stats.FreeConnections == 0 && stats.UsedConnections == 0;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理连接池失败");
                return false;
            }
        }

        /// <summary>
        /// 清理所有连接池
        /// </summary>
        public bool ClearAllPools()
        {
            try
            {
                OracleConnection.ClearAllPools();
                _logger.LogInformation("所有连接池清理完成");
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理所有连接池失败");
                return false;
            }
        }

        #endregion

        #region 异步方法支持

        /// <summary>
        /// 异步获取连接池状态
        /// </summary>
        public async Task<ConnectionPoolStats> GetPoolStatsAsync()
        {
            return await Task.Run(() => GetPoolStats());
        }

        /// <summary>
        /// 异步优化连接字符串
        /// </summary>
        public async Task<bool> OptimizeConnectionStringAsync(int maxPoolSize = 100, int connectionTimeout = 60, int minPoolSize = 10)
        {
            return await Task.Run(() =>
            {
                try
                {
                    var newSettings = GetOptimizedConnectionSettings();
                    newSettings["Max Pool Size"] = maxPoolSize.ToString();
                    newSettings["Connection Timeout"] = connectionTimeout.ToString();
                    newSettings["Min Pool Size"] = minPoolSize.ToString();

                    _logger.LogInformation("连接字符串优化完成: MaxPoolSize={MaxPoolSize}, Timeout={Timeout}, MinPoolSize={MinPoolSize}",
                        maxPoolSize, connectionTimeout, minPoolSize);

                    return true;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "优化连接字符串失败");
                    return false;
                }
            });
        }

        #endregion

        #region 性能调优

        /// <summary>
        /// 动态调整连接池大小
        /// </summary>
        public async Task<bool> AdjustPoolSizeAsync(int newMaxSize)
        {
            try
            {
                if (newMaxSize < 10 || newMaxSize > 1000)
                {
                    _logger.LogWarning("连接池大小调整超出合理范围: {NewMaxSize}", newMaxSize);
                    return false;
                }

                // 清理现有连接池
                await ClearPoolAsync();
                
                // 更新配置（运行时生效）
                var optimizedSettings = GetOptimizedConnectionSettings();
                optimizedSettings["Max Pool Size"] = newMaxSize.ToString();
                
                _logger.LogInformation("连接池大小调整为: {NewMaxSize}", newMaxSize);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "动态调整连接池大小失败");
                return false;
            }
        }

        /// <summary>
        /// 获取连接池健康检查报告
        /// </summary>
        public ConnectionHealthReport GetHealthReport()
        {
            var stats = GetPoolStats();
            var recommendations = new List<string>();

            if (stats.UsedConnections > stats.MaxPoolSize * 0.8)
            {
                recommendations.Add("连接池使用率过高，考虑增加Max Pool Size");
            }

            if (stats.FreeConnections < stats.MinPoolSize)
            {
                recommendations.Add("空闲连接不足，考虑增加Min Pool Size");
            }

            if (stats.UsedConnections == 0 && stats.FreeConnections == 0)
            {
                recommendations.Add("连接池为空，可能需要预热");
            }

            return new ConnectionHealthReport
            {
                Stats = stats,
                Recommendations = recommendations,
                IsHealthy = stats.IsHealthy && recommendations.Count == 0,
                NextCheckTime = DateTime.Now.AddMinutes(5)
            };
        }

        #endregion

        #region 私有方法

        private dynamic? GetOracleConnectionPoolStats(int connectionStringHash)
        {
            try
            {
                // 使用反射获取Oracle连接池内部状态
                var oracleConnectionType = typeof(OracleConnection);
                var poolManagerProperty = oracleConnectionType.GetProperty("PoolManager", 
                    BindingFlags.NonPublic | BindingFlags.Static);
                
                if (poolManagerProperty != null)
                {
                    var poolManager = poolManagerProperty.GetValue(null);
                    var getPoolStatsMethod = poolManager?.GetType().GetMethod("GetPoolStats");
                    
                    if (getPoolStatsMethod != null && poolManager != null)
                    {
                        var stats = getPoolStatsMethod.Invoke(poolManager, new object[] { connectionStringHash });
                        return stats;
                    }
                }

                return new { TotalConnections = 0, FreeConnections = 0, UsedConnections = 0 };
            }
            catch
            {
                return null;
            }
        }

        #endregion
    }

    #region 数据模型

    public class ConnectionPoolStats
    {
        public int ConnectionStringHash { get; set; }
        public DateTime Timestamp { get; set; }
        public int TotalConnections { get; set; }
        public int FreeConnections { get; set; }
        public int UsedConnections { get; set; }
        public int PooledConnections { get; set; }
        public int PoolSize { get; set; }
        public int MaxPoolSize { get; set; }
        public int MinPoolSize { get; set; }
        public int ConnectionTimeout { get; set; }
        public bool IsHealthy { get; set; }
    }

    public class ConnectionHealthReport
    {
        public ConnectionPoolStats Stats { get; set; } = new ConnectionPoolStats();
        public List<string> Recommendations { get; set; } = new List<string>();
        public bool IsHealthy { get; set; }
        public DateTime NextCheckTime { get; set; }
    }

    #endregion
}